home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / patches / thinkc.sit / Think ƒ / Math881.c < prev    next >
Text File  |  1989-01-16  |  6KB  |  406 lines

  1.  
  2. /*
  3.  
  4.     Math library for LightspeedC
  5.     
  6.     (C) Copyright 1986 THINK Technologies.  All rights reserved.
  7.     
  8.     For details, refer to Harbison & Steele's "C: A Reference Manual",
  9.     Chapter 11.
  10.     
  11.     Two versions of each function are defined by this library:  an
  12.     error-checking version (e.g. "sin") and a non-error-checking
  13.     version (e.g. "_sin").
  14.     
  15.     The non-underscore names can be made to refer to the non-error-
  16.     checking functions by #defining _NOERRORCHECK_ before #including
  17.     "math.h".  Doing so in THIS file suppresses the definitions of
  18.     the error-checking versions of the functions altogether.
  19.  
  20. */
  21.  
  22. /*#define _NOERRORCHECK_*/
  23. #include "Math.h"
  24.  
  25. /* useful constants */
  26. static double Zero = 0.0;
  27. static double One = 1.0;
  28. static double MinusOne = -1.0;
  29. static double Pi = PI;
  30. static double Pi2 = PI2;
  31.  
  32.  
  33. /*  seed for pseudo-random number generator  */
  34. static unsigned long seed = 1;
  35.  
  36. #ifdef _ERRORCHECK_
  37.  
  38. extern int errno;    /* defined in stdio */
  39.  
  40. #define EDOM    33
  41. #define ERANGE    34
  42.  
  43. #define ERROR    0x0000FF00 /* 68881 mask to check for exceptions */
  44.  
  45. /* GetState() and ClearExceptions() are in Math881.a */
  46. /* 
  47.     GetState returns the entire 68881 Floating-Point Status Register (FPSR);
  48.     ClearExceptions ANDs the FPSR with $00FF0000 to clear all but the quotient
  49.     byte.
  50. */
  51.  
  52. long GetState();
  53. void ClearExceptions();
  54.  
  55. #define DomainCheck(test, result)        if (test) {                    \
  56.                                             errno = EDOM;            \
  57.                                             return(result);            \
  58.                                         }
  59.                                         
  60. #define RangeCheck(target)                if (GetState() & ERROR) {    \
  61.                                             errno = ERANGE;            \
  62.                                             target = Max;            \
  63.                                         }
  64.  
  65. static short _Max[] = { 0x7FFE, 0x0000, 0x7FFF,  0xFFFF, 0xFFFF, 0xFFFF };
  66. static short _MinusMax[] = { 0xFFFE, 0x0000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF };
  67. #define Max                (* (double *) _Max)
  68. #define MinusMax        (* (double *) _MinusMax)
  69.  
  70. #else
  71. #define DomainCheck(test, result)
  72. #define RangeCheck(value)
  73. #endif
  74.  
  75. /* 
  76.     the functions rand, srand, and xfersign
  77.     get defined regardless of whether there's error checking or not.
  78. */
  79.  
  80. /*    rand - pseudo-random number generator (ANSI C standard)    */
  81.  
  82. int rand()
  83. {
  84.     seed = seed * 1103515245 + 12345;
  85.     asm {
  86.         move.w    seed,d0            ;  high word of long
  87.         andi.w    #0x7FFF,d0        ;  remove high bit
  88.     }
  89. }
  90.  
  91.  
  92. /*    srand - seed pseudo-random number generator    */
  93.  
  94. void srand(n)
  95. unsigned n;
  96. {
  97.     seed = n;
  98. }
  99.  
  100. /*    xfersign - transfer sign from one floating number to another    */
  101.  
  102. static
  103. xfersign(x, yp)
  104. double x, *yp;
  105. {
  106.     asm {
  107.         movea.l    yp,a0
  108.         bclr    #7,(a0)
  109.         tst.w    x
  110.         bpl.s    @1
  111.         bset    #7,(a0)
  112. @1    }
  113. }
  114.  
  115.  
  116. #ifdef _ERRORCHECK_
  117.  
  118. /* ---------- math functions (alphabetically) ---------- */
  119.  
  120.  
  121. /*
  122.  *  acos - inverse circular cosine
  123.  *
  124.  */
  125.  
  126. double acos(x)
  127. register double x;
  128. {
  129.     DomainCheck(x > One || x < MinusOne, Zero);
  130.     if (x == MinusOne)
  131.         return(Pi);
  132.     return(_acos(x));
  133. }
  134.  
  135.  
  136. /*
  137.  *  asin - inverse circular sine
  138.  *
  139.  */
  140.  
  141. double asin(x)
  142. register double x;
  143. {
  144.     double y = fabs(x);
  145.  
  146.     DomainCheck(y > One, Zero);
  147.     return(_asin(x));
  148. }
  149.  
  150.  
  151. /*
  152.  *  atan - inverse circular tangent - defined as macro in Math881.h
  153.  *
  154.  */
  155. double atan(x)
  156. register double x;
  157. {
  158.     return(_atan(x));
  159. }
  160.  
  161. double atan2(y, x)
  162. register double y, x;
  163. {
  164.     return(_atan2(y, x));
  165. }
  166.  
  167. /*
  168.  *  ceil - round up to an integer
  169.  *
  170.  */
  171.  
  172. double ceil(x)
  173. register double x;
  174. {
  175.     return(_ceil(x));
  176. }
  177.  
  178.  
  179. /*
  180.  *  cos - circular cosine
  181.  *
  182.  */
  183.  
  184. double cos(x)
  185. register double x;
  186. {
  187.     return(_cos(x));
  188. }
  189.  
  190.  
  191. /*
  192.  *  cosh - hyperbolic cosine
  193.  *
  194.  */
  195.  
  196. double cosh(x)
  197. register double x;
  198. {
  199.     ClearExceptions();
  200.     x = _cosh(x);
  201.     RangeCheck(x);
  202.     return(x);
  203. }
  204.  
  205.  
  206. /*
  207.  *  exp - exponential function
  208.  *
  209.  */
  210.  
  211. double exp(x)
  212. register double x;
  213. {
  214.     ClearExceptions();
  215.     x = _exp(x);
  216.     RangeCheck(x);
  217.     return(x);
  218. }
  219.  
  220.  
  221. /*
  222.  *  fabs - absolute value of a floating number
  223.  *
  224.  */
  225.  
  226. double fabs(x)
  227. register double x;
  228. {
  229.     return(_fabs(x));
  230. }
  231.  
  232.  
  233. /*
  234.  *  floor - round down to an integer
  235.  *
  236.  */
  237.  
  238. double floor(x)
  239. register double x;
  240. {
  241.     return(_floor(x));
  242. }
  243.  
  244.  
  245. /*
  246.  *  fmod - remainder function
  247.  *
  248.  *  This computes a value z, with the same sign as x, such that for some
  249.  *  integer k, k*y + z == x.
  250.  *
  251.  */
  252.  
  253. double fmod(x, y)
  254. register double x, y;
  255. {
  256.     return(_fmod(x, y));
  257. }
  258.  
  259.  
  260. /*
  261.  *  frexp - split floating number into fraction/exponent
  262.  *
  263.  *  This computes a value z, where 0.5 <= fabs(z) < 1.0, and an integer n such
  264.  *  that z*(2^n) == x.
  265.  *
  266.  */
  267.  
  268. double frexp(x, nptr)
  269. register double x;
  270. register int *nptr;
  271. {
  272.     return(_frexp(x, nptr));
  273. }
  274.  
  275.  
  276. /*
  277.  *  ldexp - combine fraction/exponent into a floating number
  278.  *
  279.  */
  280.  
  281. double ldexp(x, n)
  282. register double x;
  283. register int n;
  284. {
  285.     return(_ldexp(x, n));
  286. }
  287.  
  288.  
  289. /*
  290.  *  log - natural logarithm
  291.  *
  292.  */
  293.  
  294. double log(x)
  295. register double x;
  296. {
  297.     DomainCheck(x <= 0, MinusMax);
  298.     return(_log(x));
  299. }
  300.  
  301.  
  302. /*
  303.  *  log10 - logarithm base 10
  304.  *
  305.  */
  306.  
  307. double log10(x)
  308. register double x;
  309. {
  310.     DomainCheck(x <= 0, MinusMax);
  311.     return(_log10(x));
  312. }
  313.  
  314.  
  315. /*
  316.  *  modf - split a floating number into fraction/integer
  317.  *
  318.  */
  319.  
  320. double modf(x, nptr)
  321. double x, *nptr;
  322. {
  323.     return(_modf(x, nptr));
  324. }
  325.  
  326.  
  327. /*    pow - power function (exponentiation)    */
  328.  
  329. double pow(x, y)
  330. register double x, y;
  331. {
  332.     return(_pow(x, y));        /* _pow() does the proper error checking. */
  333. }
  334.  
  335.  
  336. /*
  337.  *  sin - circular sine
  338.  *
  339.  */
  340.  
  341. double sin(x)
  342. register double x;
  343. {
  344.     return(_sin(x));
  345. }
  346.  
  347.  
  348. /*
  349.  *  sinh - hyperbolic sine
  350.  *
  351.  */
  352.  
  353. double sinh(x)
  354. register double x;
  355. {
  356.     register double y;
  357.     
  358.     ClearExceptions();
  359.     y = _sinh(x);
  360.     RangeCheck(y);
  361.     return(y);
  362. }
  363.  
  364.  
  365. /*
  366.  *  sqrt - square root
  367.  *
  368.  */
  369.  
  370. double sqrt(x)
  371. register double x;
  372. {
  373.     DomainCheck(x < 0, Zero);
  374.     return(_sqrt(x));
  375. }
  376.  
  377.  
  378. /*
  379.  *  tan - circular tangent
  380.  *
  381.  */
  382.  
  383. double tan(x)
  384. register double x;
  385. {
  386.     ClearExceptions();
  387.     x = _tan(x);
  388.     RangeCheck(x);
  389.     return(x);
  390. }
  391.  
  392.  
  393. /*
  394.  *  tanh - hyperbolic tangent
  395.  *
  396.  */
  397.  
  398. double tanh(x)
  399. double x;
  400. {
  401.     return(_tanh(x));
  402. }
  403.  
  404. #endif _ERRORCHECK_
  405.  
  406.